<?php
/**
* 
* useage in init function of module config controllerMap
* 
* public function init()
    {
        //...
        $this->controllerMap = array(
            'category'=>array(
                'class'=>'Admin.controllers.TermController',
                'taxModule'=>'<module id>',
                'voc'=>'<vocabulary alias|id>',
                'actions'=>array(
                    'admin'=>'path.to.AdminAction',
                    'update'=>'path.to.UpdateAction',
                    ...
                )
            ),
        );
        //...
    }
* 
* view category "<module id>/category"
* 
*/
class TermController extends BackOfficeController
{
    public $defaultAction = 'admin';
	/**
	 * @var string the default layout for the views. Defaults to '//layouts/column2', meaning
	 * using two-column layout. See 'protected/views/layouts/column2.php'.
	 */
	public $layout='//layouts/column2';
    public $taxModule = 'system';
    public $voc = 0;
    //extend, add new or overide logic of Admin, create, update actions
    public $actions = array();
    
    private $_vocabulary;
    
    public function getVocabulary()
    {
        if ($this->_vocabulary === null)
        {
            if (is_numeric($this->voc))
                $this->_vocabulary = Vocabulary::model()->findByPk($this->voc);
            else
                $this->_vocabulary = Vocabulary::model()->findByAttributes(array('alias'=>$this->voc));
        }
        return $this->_vocabulary;
    }
    

    /**
     * Renders a view.
     *
     * The named view refers to a PHP script (resolved via {@link getViewFile})
     * that is included by this method. If $data is an associative array,
     * it will be extracted as PHP variables and made available to the script.
     *
     * This method differs from {@link render()} in that it does not
     * apply a layout to the rendered result. It is thus mostly used
     * in rendering a partial view, or an AJAX response.
     *
     * @param string $view name of the view to be rendered. See {@link getViewFile} for details
     * about how the view script is resolved.
     * @param array $data data to be extracted into PHP variables and made available to the view script
     * @param boolean $return whether the rendering result should be returned instead of being displayed to end users
     * @param boolean $processOutput whether the rendering result should be postprocessed using {@link processOutput}.
     * @return string the rendering result. Null if the rendering result is not required.
     * @throws CException if the view does not exist
     * @see getViewFile
     * @see processOutput
     * @see render
     */
    public function renderPartial($view,$data=null,$return=false,$processOutput=false)
    {
        if(($viewFile=$this->getViewFile($view))===false)
        {
            $view = 'Admin.views.term.'.$view;
        }
        return parent::renderPartial($view,$data,$return,$processOutput);
    }
    
    public function actions()
    {
        return CMap::mergeArray(array(
            'index'=>array('class'=>'Admin.controllers.term.AdminAtion'),
            'admin'=>array('class'=>'Admin.controllers.term.AdminAtion'),
            'create'=>array('class'=>'Admin.controllers.term.UpdateAtion'),
            'update'=>array('class'=>'Admin.controllers.term.UpdateAtion'),
        ), $this->actions);
    }

	/**
	 * Deletes a particular model.
	 * If deletion is successful, the browser will be redirected to the 'index' page.
	 * @param integer $id the ID of the model to be deleted
	 */
	public function actionDelete()
	{
        if (($id = $this->get('id',null)) !== null) {
            $ids = is_numeric($id) ? array($id) : explode(',',$id);
            
            // delete one or multiple objects given the list of object IDs
            $result = FSM::run('Core.Term.delete', array('ids' => $ids));
            if ($result->hasErrors()) {
                echo $result->getError('ErrorCode');
            } elseif(!Yii::app()->request->isAjaxRequest) {
                // only redirect user to the admin page if it is not an AJAX request
                $this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin'));
            }
        } else {
            throw new CHttpException(400,Yii::t('Core','Cannot delete item with the given ID.'));
        }
	}
    
    public function actionUpdateOrder()
    {
        $ids = $this->get('items', array());
        if (count($ids)) {
            foreach ($ids as $id => $parentId) {
                $orders = array();
                if ($parentId == 'root') {
                    $orders = array_keys($ids, $parentId);
                    $parentId = 0;
                }
                else {
                    $parentId = (int) $parentId;
                    $orders = array_keys($ids, $parentId);
                }
                $order = 0;
                if (count($orders))
                    $order = (int) array_search($id, $orders);
                $order++;
                Term::model()->updateByPk($id, array('ordering'=>$order));
                $model = TermHierarchy::model()->findByAttributes(array('term_id'=>$id));
                if (is_object($model))
                {
                    if ($parentId)
                        TermHierarchy::model()->updateAll(array('parent_id'=>$parentId), 'term_id=:term_id', array(':term_id'=>$id));
                    else
                        TermHierarchy::model()->deleteAllByAttributes(array('term_id'=>$id));
                }
                elseif ($parentId)
                {
                    $model = new TermHierarchy;
                    $model->term_id = $id;
                    $model->parent_id = $parentId;
                    $model->save();
                }
            }
        }
    }
    
    public function actionStatus()
    {
        $termId = $this->get('id', 0);
        if ($termId)
        {
            $model = Term::model()->findByPk($termId);
            if (is_object($model))
            {
                $model->state = $model->state == Term::STATE_ACTIVE ? Term::STATE_DEACTIVE : Term::STATE_ACTIVE;
                if (!$model->save(false,array('state')))
                {
                    Yii::log(CVarDumper::dumpAsString($model->getErrors()), CLogger::LEVEL_ERROR);
                }
            }
        }
    }
    
    public function actionBulkCreate()
    {
        $v = $this->get('v', 0);
        $module = $this->get('m', 'Admin');
        
        $vob = Vocabulary::model()->findByPk($v);
        if (!is_object($vob))
            throw new CHttpException(400,Yii::t('Core','Invalid Type ID.'));
            
        $model = new Term('bulk_save');
            
        if (Yii::app()->request->IsPostRequest && isset($_POST['Term']))
        {
            $model->setAttributes($_POST['Term'],FALSE);
            $model->parentId = $this->post('Term[parentId]','');
            $model->names = $this->post('Term[names]','');
            if ($model->validate())
            {
                $catNames = explode("\n",$model->names);
                $result = FSM::run('Core.Term.bulkCreate', array('names'=>$catNames,'parentId'=>$model->parentId,'vocabularyId'=>$model->v_id));
                if (! $result->hasErrors())
                {
                    $this->message = Yii::t('Core','Items has been saved successfully.');
                    $this->redirect($this->createUrl('bulkCreate',array('v'=>$v,'m'=>$module)));
                }
            }
        } else
        {
            $model->v_id = $v;
        }

        $this->render('bulk_create', array(
            'model' => $model,
            'v'=>$v,
            'module'=>$module,
        ));    
    }
}
